#include "mainwindow.h"

#include <QApplication>
#include "jencode.h"
extern "C" {
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libavutil/pixdesc.h>
#include <libavutil/imgutils.h>
#include <libswscale/swscale.h>
#include <libavdevice/avdevice.h>
}
#include<iostream>
#define Err(re) if(re!=0) PrintErr(re)
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();
    JEncode e;
    const  char* fileName = "in.mp4";
    AVFormatContext* ic = nullptr;
    int re =avformat_open_input(&ic,fileName,NULL,NULL);

    Err(re);

    re = avformat_find_stream_info(ic,NULL);
    Err(re);

    int audio_stream=-1;
    int video_stream=-1;

    for(int i=0;i<ic->nb_streams;i++){
        if(ic->streams[i]->codecpar->codec_type==AVMEDIA_TYPE_AUDIO)//音频索引
        {
            audio_stream = i;
        }
        if(ic->streams[i]->codecpar->codec_type==AVMEDIA_TYPE_VIDEO)//视频索引
        {
            video_stream = i;
        }
    }

    //移动时间
    double begin_time = 10.0;
    double end_time = 20.0;
    double begin_pts_video = begin_time * (double)ic->streams[video_stream]->time_base.den/(double)ic->streams[video_stream]->time_base.num;
    double begin_pts_audio = begin_time * (double)ic->streams[audio_stream]->time_base.den/(double)ic->streams[audio_stream]->time_base.num;
    double end_pts_video = end_time * (double)ic->streams[video_stream]->time_base.den/(double)ic->streams[video_stream]->time_base.num;

    //移动到对于时间戳的地方
    re = av_seek_frame(ic,video_stream,begin_pts_video,AVSEEK_FLAG_FRAME|AVSEEK_FLAG_BACKWARD);
    Err(re);
    //输出上下文

    const char* outFileName = "out.mp4";
    AVFormatContext* ec = nullptr;
    re =avformat_alloc_output_context2(&ec,NULL,NULL,outFileName);

    AVStream* mvs=avformat_new_stream(ec,NULL);//视频流
    AVStream* mas=avformat_new_stream(ec,NULL);//音频流


    avio_open(&ec->pb,outFileName,AVIO_FLAG_WRITE);
    mvs->time_base = ic->streams[video_stream]->time_base;
    mas->time_base = ic->streams[audio_stream]->time_base;


    avcodec_parameters_copy(mvs->codecpar,ic->streams[video_stream]->codecpar);
    avcodec_parameters_copy(mas->codecpar,ic->streams[audio_stream]->codecpar);

    re = avformat_write_header(ec,NULL);
    Err(re);

    AVPacket pkt;

    for(;;)
    {
        re = av_read_frame(ic,&pkt);
        if(re!=0)
        {
            break;
        }

        AVStream* in_stream = ic->streams[pkt.stream_index];
        AVStream* out_stream = nullptr;

        int64_t offset = 0;//时间戳的偏移，用于阶段前面部分
        if(pkt.stream_index == video_stream)
        {
            if(pkt.pts>end_pts_video) break;
            out_stream = ec->streams[0];
            offset = begin_pts_video;

        }
        else if(pkt.stream_index == audio_stream){
            out_stream = ec->streams[1];
            offset = begin_pts_audio;
        }

        pkt.pts = av_rescale_q_rnd(pkt.pts-offset,in_stream->time_base,out_stream->time_base,(AVRounding)(AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX));
        pkt.dts = av_rescale_q_rnd(pkt.dts-offset,in_stream->time_base,out_stream->time_base,(AVRounding)(AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX));
        pkt.duration = av_rescale_q(pkt.duration,in_stream->time_base,out_stream->time_base);

        av_interleaved_write_frame(ec,&pkt);//该函数会自己处理pkt引用计数
        Err(re);
    }


    re = av_write_trailer(ec);

    return a.exec();
}
